home *** CD-ROM | disk | FTP | other *** search
- /* National Institute of Standards and Technology (NIST)
- /* National Computer System Laboratory (NCSL)
- /* Office Systems Engineering (OSE) Group
- /* ********************************************************************
- /* D I S C L A I M E R
- /* (March 8, 1989)
- /*
- /* There is no warranty for the NIST NCSL OSE SGML parser and/or the NIST
- /* NCSL OSE SGML parser validation suite. If the SGML parser and/or
- /* validation suite is modified by someone else and passed on, NIST wants
- /* the parser's recipients to know that what they have is not what NIST
- /* distributed, so that any problems introduced by others will not
- /* reflect on our reputation.
- /*
- /* Policies
- /*
- /* 1. Anyone may copy and distribute verbatim copies of the SGML source
- /* code as received in any medium.
- /*
- /* 2. Anyone may modify your copy or copies of SGML parser source code or
- /* any portion of it, and copy and distribute such modifications provided
- /* that all modifications are clearly associated with the entity that
- /* performs the modifications.
- /*
- /* NO WARRANTY
- /* ===========
- /*
- /* NIST PROVIDES ABSOLUTELY NO WARRANTY. THE SGML PARSER AND VALIDATION
- /* SUITE ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
- /* EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- /* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- /* THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS
- /* WITH YOU. SHOULD THE SGML PARSER OR VALIDATION SUITE PROVE DEFECTIVE,
- /* YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
- /*
- /* IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW WILL NIST BE LIABLE FOR
- /* DAMAGES, INCLUDING ANY LOST PROFITS, LOST MONIES, OR OTHER SPECIAL,
- /* INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR
- /* INABILITY TO USE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA
- /* BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY THIRD PARTIES OR A
- /* FAILURE OF THE PROGRAM TO OPERATE WITH PROGRAMS NOT DISTRIBUTED BY
- /* NIST) THE PROGRAM, EVEN IF YOU HAVE BEEN ADVISED OF THE POSSIBILITY OF
- /* SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY.
- */
-
- /************************************************************************/
- /* TITLE: SGML PARSER */
- /* SYSTEM: DTD PROCESSOR */
- /* SUBSYSTEM: */
- /* SOURCE FILE: DETTRAV.C */
- /* AUTHOR: Michael Garris */
- /* */
- /* DATE CREATED: */
- /* LAST MODIFIED: */
- /* */
- /* REVISIONS */
- /* WHEN WHO WHY */
- /************************************************************************/
- #include <stdio.h>
- #include "detdefs.h"
- #include "detglbl.h"
-
- /************************************************************************/
- /************************************************************************/
- /* PROCINORDR is a traversal which visits every state in an FSA starting*/
- /* at the start state "startstate". */
- /************************************************************************/
- void procinordr(startstate,finalstate)
- STATE *startstate,*finalstate;
- {
- STATE *node;/* current state being visited */
-
- /* set current node to "startstate" */
- node = startstate;
- /* if the finalstate has not be reached ... */
- if(startstate != finalstate){
- /* if the current state's left pointer is not NULL, not point*/
- /* back, and not looping directly back to itself ... */
- if((node->lptr != NULL) && (node->llabel != BACK)
- && (node != node->lptr)){
- /* continue to traverse left */
- procinordr(node->lptr,finalstate);
- }
- /* the current node's left pointer is either NULL, pointing */
- /* back, or pointing directly to itself, so invoke "procnode" */
- procnode(node);
- /* now look right */
- /* if current node's right pointer is not NULL, not pointing */
- /* back, and not looping directly back to itself ... */
- if((node->rptr != NULL) && (node->rlabel != BACK)
- && (node != node->rptr)){
- /* continue to traverse right */
- procinordr(node->rptr,finalstate);
- }
- }
- /* otherwise final state has been found */
- else{
- /* process the final state */
- procnode(startstate);
- }
- }
- /************************************************************************/
- /************************************************************************/
- /* PROCNODE takes a state structure and prints out the state's address, */
- /* the state's left pointer address and label, and the state's right */
- /* pointer address and label. */
- /************************************************************************/
- void procnode(node)
- STATE *node;
- {
- #ifdef DEBUG
- printf("for node at address %04x\n", node);
- printf(" lptr = %04x, llabel = %04x, linst = %d\n",
- node->lptr, node->llabel, node->linst);
- printf(" rptr = %04x, rlabel = %04x, rinst = %d\n",
- node->rptr, node->rlabel, node->rinst);
- printf("___________________________________\n");
- #else
- return;
- #endif
- }
- /************************************************************************/
- /************************************************************************/
- /* PROCDET is a traversal which visits every state in an FSA starting */
- /* at the start state "startstate", and for each state visited, it calls*/
- /* a procedure to check the current state passed for "ambiguity". */
- /************************************************************************/
- void procdet(startstate,finalstate)
- STATE *startstate,*finalstate;
- {
- register STATE *node;/* current state being looked at */
- STATE *currnode[BUFFSIZE];/* list to hold all states visited */
- /* while a state is tested for ambiguity */
- int nodeindex = 0;/* subscript to "currnode" */
- int toklist[BUFFSIZE];/* list to hold all edges labeled with */
- /* tokens and their associated instance code*/
- int *tokindex = toklist;/* pointer to toklist initialized to the */
- /* beginning of toklist */
- int *tokmax = tokindex + BUFFSIZE - 2;
- register int i;
- memset((char *)toklist, 0, BUFFSIZE);
- /* set current state to state that was passed */
- node = startstate;
- /* if the state passed is not the finalstate ...*/
- if(startstate != finalstate){
- /* if the left pointer of the current state is not NULL, not */
- /* pointing back, and not looping directly to itself ... */
- if((node->lptr != NULL) && (node->llabel != BACK)
- && (node != node->lptr)){
- /* continue to traverse left */
- procdet(node->lptr,finalstate);
- }
- /* otherwise send the current state and a state list to a */
- /* procedure to detect any ambiguity from that state */
- findlabels(node,currnode,&nodeindex,toklist,&tokindex,tokmax);
- /* if the right pointer of the current state is not NULL, not */
- /* pointing back, and not looping directly to itself ...*/
- if((node->rptr != NULL) && (node->rlabel != BACK)
- && (node != node->rptr)){
- /* continue to traverse right */
- procdet(node->rptr,finalstate);
- }
- }
- /* otherwise the current state is the final state */
- else{
- /* invoke procedure to determine ambiguity on the final state */
- findlabels(startstate,currnode,&nodeindex,toklist,&tokindex,tokmax);
- }
- }
- /************************************************************************/
- /************************************************************************/
- /* FINDLABELS takes a state from an FSA and traverses all unique paths */
- /* from that state recording each first occurance of a non-NULL edge */
- /* on each unique path. On completing each unique path, this procedure */
- /* searches a list of the non-NUll edges seen and determines is the */
- /* state is "ambiguous" according to the definition stated by SGML. */
- /************************************************************************/
- void findlabels(node,currnode,nodeindex,toklist,ptrin,tokmax)
- register STATE *node;
- STATE *currnode[];
- int *toklist,**ptrin;
- int *nodeindex;
- int *tokmax;
- {
- int *tokindex = *ptrin;
-
- /* put the current state's address into the list of states visited */
- if (*nodeindex >= BUFFSIZE) {
- printf("overflow in findlabels\n");
- exit(0);
- }
- currnode[(*nodeindex)] = node;
- /* increment the subscript at the location nodeindex */
- *nodeindex = *nodeindex + 1;
- /* if the current state's left edge is labelled EMPTY or BACK, and */
- /* the current state's left edge is not pointing to a state already*/
- /* visited by this traversal on the state passed by procdet ... */
- if(node->llabel < 0){
- register int i;
- register STATE **jcurrnode = currnode;
- register STATE *jnode = node->lptr;
- for (i = 0; i < *nodeindex; i++) {
- if (*jcurrnode++ == jnode)
- goto OUT1;
- }
- /* continue to traverse left on a unique path */
- findlabels(node->lptr,currnode,nodeindex,toklist,&tokindex, tokmax);
- }
- OUT1:
- /* if the current state is not pointing left to a NULL, EMPTY, and */
- /* BACK ...*/
- if((node->lptr != NULL) && (node->llabel != EMPTY)
- && (node->llabel != BACK)){
- /* then the edge is labelled with a token, so print it out */
- if(searchamb(node->llabel,node->linst,toklist,tokindex))
- ambmodel = TRUE;
- if((tokindex + 2) >= tokmax) {
- printf("tokindex overflow in findlabels()\n");
- exit(0);
- }
- *tokindex++ = node->llabel;
- *tokindex++ = node->linst;
- }
-
- /* if the current state's right edge is labelled EMPTY or BACK, and */
- /* the current state's right edge is not pointing to a state already*/
- /* visited by this traversal on the state passed by procdet ... */
- if(node->rlabel < 0){
- register int i;
- register STATE **jcurrnode = currnode;
- register STATE *jnode = node->rptr;
- for (i = 0; i < *nodeindex; i++) {
- if (*jcurrnode++ == jnode)
- goto OUT2;
- }
- findlabels(node->rptr,currnode,nodeindex,toklist,&tokindex,tokmax);
- }
- OUT2:
- /* otherwise the edge is labelled by a token */
- if((node->rptr != NULL) && (node->rlabel != EMPTY)
- && (node->rlabel != BACK)){
- /* print the labelled edge out */
- if(searchamb(node->rlabel,node->rinst,toklist,tokindex))
- ambmodel = TRUE;
- if((tokindex + 2) >= tokmax) {
- printf("tokindex overflow in findlabels()\n");
- exit(0);
- }
- *tokindex++ = node->rlabel;
- *tokindex++ = node->rinst;
- }
- *ptrin = tokindex;
- }
- /************************************************************************/
- /************************************************************************/
- /* SEARCHAMB*/
- /************************************************************************/
- int searchamb(label,inst,toklist,tokindex)
- int label,inst,*toklist,*tokindex;
- {
- int i;
- register int *ptr = toklist;
-
- while(ptr != tokindex){
- if(label == *ptr++){
- if(inst != *ptr++)
- return(TRUE);
- }
- else
- ++ptr;
- }
- return(FALSE);
- }
- /************************************************************************/
- /************************************************************************/
- /* SSEARCH searches a list of states for a match on the current state */
- /* "node". If a match occurs then the function returns FALSE, otherwise*/
- /* the function returns TRUE. */
- int ssearch(node,currnode,nodeindex)
- STATE *node,*currnode[];
- register int nodeindex;
- {
- register int i,k = 0;
-
- for(i = 0; i < nodeindex; ++i){
- if(currnode[k++] == node)
- return(FALSE);
- }
- return(TRUE);
- }
- /************************************************************************/
-